package org.etherframework.tests.features.dependency
{
	import org.etherframework.core.IModule;
	import org.etherframework.dependency.Dependency;
	import org.etherframework.dependency.IDependencies;
	import org.etherframework.tests.features.dependency.models.ComplexModel;
	import org.etherframework.tests.features.dependency.models.IInstanceModel2;
	import org.etherframework.tests.features.dependency.models.IInterfacedModel;
	import org.etherframework.tests.features.dependency.models.InstanceModel;
	import org.etherframework.tests.features.dependency.models.InstanceModel2;
	import org.etherframework.tests.features.dependency.models.InterfacedModel;
	import org.etherframework.tests.features.dependency.models.NoneExistentModel;
	import org.etherframework.tests.features.dependency.models.SimpleModel;
	import org.etherframework.tests.features.dependency.models.SingletonModel;
	import org.etherframework.tests.utils.TestUtility;
	import org.hamcrest.assertThat;
	import org.hamcrest.object.notNullValue;
	import org.hamcrest.object.nullValue;

	public class when_removing_dependencies
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _module:IModule;
		private static var _d:IDependencies;
		
		private static var _simpleModel:SimpleModel;
		private static var _complexModel:ComplexModel;
		private static var _interfacedModel:InterfacedModel;
		private static var _singletonModel:SingletonModel;
		private static var _instanceModel:InstanceModel;
		private static var _instanceModel2:InstanceModel2;
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			_module = _testUtility.createModule();
			_d = _module.dependencies;
			_d.addClass(SimpleModel);
			_d.addClass(ComplexModel);
			_d.addClass(InterfacedModel, IInterfacedModel);
			_d.addSingleton(SingletonModel);
			_d.addInstance(new InstanceModel());
			_d.addInstance(new InstanceModel2(), IInstanceModel2);
			
			_simpleModel = _d.getDependency(SimpleModel).getInstance() as SimpleModel
			_complexModel = _d.getDependency(ComplexModel).getInstance() as ComplexModel;
			_interfacedModel = _d.getDependency(IInterfacedModel).getInstance() as InterfacedModel;
			_singletonModel = _d.getDependency(SingletonModel).getInstance() as SingletonModel;
			_instanceModel = _d.getDependency(InstanceModel).getInstance() as InstanceModel;
			_instanceModel2 = _d.getDependency(IInstanceModel2).getInstance() as InstanceModel2;
			
			_d.removeDependency(_d.getDependency(SimpleModel));
			_d.removeDependency(_d.getDependency(ComplexModel));
			_d.removeDependency(_d.getDependency(IInterfacedModel));
			_d.removeDependency(_d.getDependency(SingletonModel));
			_d.removeDependency(_d.getDependency(InstanceModel));
			_d.removeDependency(_d.getDependency(IInstanceModel2));
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			_testUtility.dispose();
			SimpleModel.instanceCounter = 0;
			ComplexModel.instanceCounter = 0;
			InterfacedModel.instanceCounter = 0;
			SingletonModel.instanceCounter = 0;
			InstanceModel.instanceCounter = 0;
			InstanceModel2.instanceCounter = 0;
		}
		
		[Test(order=1)]
		public function dependencies_should_be_removed():void
		{
			var dependency:Dependency;
			
			dependency = _d.getDependency(SimpleModel);
			assertThat(dependency, nullValue());
			dependency = _d.getDependency(ComplexModel);
			assertThat(dependency, nullValue());
			dependency = _d.getDependency(IInterfacedModel);
			assertThat(dependency, nullValue());
			dependency = _d.getDependency(SingletonModel);
			assertThat(dependency, nullValue());
			dependency = _d.getDependency(InstanceModel);
			assertThat(dependency, nullValue());
			dependency = _d.getDependency(IInstanceModel2);
			assertThat(dependency, nullValue());
		}
		
		[Test(order=2)]
		public function it_should_throw_an_error_when_dependency_does_not_exist():void
		{
			var err:Error;
			
			try {
				_d.removeDependency(new Dependency(NoneExistentModel, null, true, false, null, null));
			} catch (e:*) { err = e; }
			assertThat(err, notNullValue());
			
			err = null;
			try {
				_d.removeDependency(null);
			} catch (e:*) { err = e; }
			assertThat(err, notNullValue());
		}
	}
}